"""
Steam交易状态刷新定时任务
定时为活跃账号刷新Steam交易状态
"""
import logging
import random
import threading
import time
from typing import Dict, List, Any, Optional
import sys
from pathlib import Path

# 添加项目根目录到Python路径
sys.path.append(str(Path(__file__).parent.parent))

from com.db.scan_account_manager import ScanAccountManager
from reqapi.steam_trade_status_refresh import SteamTradeStatusRefreshApi

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class SteamTradeStatusScheduler:
    """Steam交易状态刷新定时任务调度器"""
    
    def __init__(self):
        """初始化调度器"""
        self.account_manager = ScanAccountManager()
        self.running = False
        self.threads = {}  # 存储每个账号的定时线程
        self.lock = threading.Lock()  # 线程锁，用于安全操作共享资源
    
    def start(self):
        """启动定时任务"""
        if self.running:
            logger.warning("定时任务已经在运行中")
            return
            
        logger.info("启动Steam交易状态刷新定时任务")
        self.running = True
        
        # 启动主线程，负责定期检查和更新账号列表
        self.main_thread = threading.Thread(target=self._main_loop)
        self.main_thread.daemon = True  # 设置为守护线程，主程序退出时自动结束
        self.main_thread.start()
    
    def stop(self):
        """停止定时任务"""
        if not self.running:
            logger.warning("定时任务未在运行")
            return
            
        logger.info("停止Steam交易状态刷新定时任务")
        self.running = False
        
        # 等待主线程结束
        if hasattr(self, 'main_thread') and self.main_thread.is_alive():
            self.main_thread.join(timeout=5)
            
        # 清理所有账号线程
        with self.lock:
            for account_id, thread_info in list(self.threads.items()):
                if 'event' in thread_info:
                    thread_info['event'].set()  # 通知线程停止
            
            # 清空线程字典
            self.threads.clear()
    
    def _main_loop(self):
        """主循环，负责定期检查和更新账号列表"""
        while self.running:
            try:
                # 获取活跃账号列表
                active_accounts = self.account_manager.get_active_accounts()
                logger.info(f"获取到 {len(active_accounts)} 个活跃账号")
                
                # 更新账号线程
                self._update_account_threads(active_accounts)
                
                # 每5分钟检查一次账号列表
                time.sleep(300)
            except Exception as e:
                logger.error(f"主循环发生错误: {str(e)}")
                time.sleep(60)  # 发生错误时等待1分钟后重试
    
    def _update_account_threads(self, accounts: List[Dict[str, Any]]):
        """更新账号线程
        
        Args:
            accounts: 活跃账号列表
        """
        with self.lock:
            # 当前活跃账号ID集合
            active_account_ids = {account['id'] for account in accounts}
            
            # 移除不再活跃的账号线程
            for account_id in list(self.threads.keys()):
                if account_id not in active_account_ids:
                    logger.info(f"账号 {account_id} 不再活跃，停止其定时任务")
                    if 'event' in self.threads[account_id]:
                        self.threads[account_id]['event'].set()  # 通知线程停止
                    del self.threads[account_id]
            
            # 为新的活跃账号创建线程
            for account in accounts:
                account_id = account['id']
                if account_id not in self.threads:
                    logger.info(f"为账号 {account_id} ({account.get('nickname', '')}) 创建定时任务")
                    
                    # 创建停止事件
                    stop_event = threading.Event()
                    
                    # 创建并启动线程
                    thread = threading.Thread(
                        target=self._account_refresh_loop,
                        args=(account, stop_event)
                    )
                    thread.daemon = True
                    thread.start()
                    
                    # 保存线程信息
                    self.threads[account_id] = {
                        'thread': thread,
                        'event': stop_event,
                        'account': account
                    }
    
    def _account_refresh_loop(self, account: Dict[str, Any], stop_event: threading.Event):
        """账号刷新循环
        
        Args:
            account: 账号信息
            stop_event: 停止事件
        """
        account_id = account['id']
        nickname = account.get('nickname', '')
        device_id = account.get('device_id', '')
        auth_token = account.get('uu_token', '')
        uk = account.get('uk', '')
        
        logger.info(f"账号 {account_id} ({nickname}) 刷新循环开始")
        
        while not stop_event.is_set() and self.running:
            try:
                # 生成30-60分钟的随机间隔（秒）
                interval = random.randint(30 * 60, 60 * 60)
                
                # 刷新Steam交易状态
                api = SteamTradeStatusRefreshApi(
                    device_id=device_id,
                    auth_token=auth_token,
                    uk=uk
                )
                result = api.refresh()
                
                if result and result.code == 0:
                    status_tip = result.data.steamTradeStatusTip if result.data else "未知"
                    logger.info(f"账号 {account_id} ({nickname}) 刷新Steam交易状态成功: {status_tip}")
                else:
                    error_msg = result.msg if result else "请求失败"
                    logger.warning(f"账号 {account_id} ({nickname}) 刷新Steam交易状态失败: {error_msg}")
                
                # 等待指定间隔或直到收到停止信号
                logger.info(f"账号 {account_id} ({nickname}) 将在 {interval//60} 分钟后再次刷新")
                stop_event.wait(interval)
                
            except Exception as e:
                logger.error(f"账号 {account_id} ({nickname}) 刷新循环发生错误: {str(e)}")
                # 发生错误时等待5分钟后重试
                stop_event.wait(300)
        
        logger.info(f"账号 {account_id} ({nickname}) 刷新循环结束")


# 单例模式
_scheduler_instance = None

def get_scheduler() -> SteamTradeStatusScheduler:
    """获取调度器单例
    
    Returns:
        SteamTradeStatusScheduler: 调度器实例
    """
    global _scheduler_instance
    if _scheduler_instance is None:
        _scheduler_instance = SteamTradeStatusScheduler()
    return _scheduler_instance


if __name__ == "__main__":
    # 测试定时任务
    try:
        scheduler = get_scheduler()
        scheduler.start()
        
        logger.info("定时任务已启动，按Ctrl+C停止")
        
        # 保持主线程运行
        while True:
            time.sleep(1)
            
    except KeyboardInterrupt:
        logger.info("收到停止信号")
    finally:
        # 确保停止调度器
        if 'scheduler' in locals():
            scheduler.stop()
        logger.info("定时任务已停止")
